﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Sicurezza.Client.Manager;
using OpenSSL.X509;
using OpenSSL.Crypto;
using OpenSSL.Core;
using Sicurezza.Entita;

namespace Sicurezza.Client.Controlli
{
    public partial class RequestControl : UserControl
    {

        private X509Certificate Certificato { get; set; }
        private RSA key { get; set; }
        private string CurrentReqId;

        public event EventHandler GeneratingKeys;
        public event EventHandler GeneratingKeysEnd;
        public event EventHandler SendingRequest;
        public event EventHandler SendingRequestEnd;
        public event EventHandler RequestAccepted;
        public event EventHandler RequestSaved;
        public event EventHandler RequestEnd;
        public event EventHandler RenewAccepted;

        public RequestControl()
        {
            InitializeComponent();
        }


        private void ShowRequest(X509Request r)
        {
            certificateViewControl.RequestMode = true;
            certificateViewControl.ReadOnlyMode = true;
            certificateViewControl.PublicKeyAlgorithm = "rsaEncryption";
            certificateViewControl.PublicKey = r.PublicKey.GetRSA().PublicModulus.ToHexString();
            certificateViewControl.SubjectC = r.Subject.Country;
            certificateViewControl.SubjectO = r.Subject.Organization;
            certificateViewControl.SubjectOU = r.Subject.OrganizationUnit;
            certificateViewControl.SubjectCN = r.Subject.Common;


            string keyUsage = r.Subject.GetTextByName("keyUsage");
            if (keyUsage != null)
            {
                certificateViewControl.DigitalSignature = keyUsage.Contains("digitalSignature");
                certificateViewControl.KeyEncipherment = keyUsage.Contains("keyEncipherment");
            }

            certificateViewControl.SubjectEmail = r.Subject.GetTextByName("subjectAltName").Substring(6);

            RequestButton.Enabled = false;
            VerifyButton.Enabled = true;
        }

        public void GenerateKeys(int lenght)
        {
            
            GeneratingKeys(null, null);

            key = KeyManager.Generate(lenght);

            certificateViewControl.EditMode = true;
            certificateViewControl.PublicKeyAlgorithm = "rsaEncryption";
            certificateViewControl.PublicKey = key.PublicModulus.ToHexString();

            GeneratingKeysEnd(null, null);
            
        }

        public void Reset()
        {
            RequestButton.Enabled = true;
            VerifyButton.Enabled = false;
            certificateViewControl.Reset();
            Visible = false;
        }

        public void Open(string SelectedReqId)
        {
            CurrentReqId = SelectedReqId;
            X509Request r = RequestManager.Get(SelectedReqId);
            ShowRequest(r);
        }

        private void RequestButton_Click_1(object sender, EventArgs e)
        {
            RequestButton.Enabled = false;

            string request = X509Manager.CreateRequest(
                key,
                certificateViewControl.SubjectC,
                certificateViewControl.SubjectO,
                certificateViewControl.SubjectOU,
                certificateViewControl.SubjectCN,
                certificateViewControl.SubjectEmail,
                certificateViewControl.DigitalSignature,
                certificateViewControl.KeyEncipherment
                );

            SendingRequest(null, null);

            string ReqId = RequestManager.Send(request);

            SendingRequestEnd(null, null);



            MsgBox.RequestOk();

            string password = "";
            PasswordForm pf = new PasswordForm();
            do
            {
                if (pf.ShowDialog() == DialogResult.OK)
                    password = pf.Password;
            } while (string.IsNullOrEmpty(password));

            FileManager.SaveRequest(ReqId, request, key, password);



            X509Request r = RequestManager.Get(ReqId);
            CurrentReqId = ReqId;
            ShowRequest(r);

            RequestEnd(null, null);
        }

        private void VerifyButton_Click_1(object sender, EventArgs e)
        {
            string cert;
            try
            {
                if (CurrentReqId.Contains("req-"))
                    cert = RequestManager.Check(CurrentReqId);
                else
                    cert = RenewManager.Check(CurrentReqId);
                if (string.IsNullOrEmpty(cert))
                {
                    MsgBox.VerifyKo();
                }
                else
                {
                    MsgBox.VerifyOk();
                    RequestAccepted(cert, null);

                }
            }
            catch (ManagerException ex)
            {
                MsgBox.Rejected(ex.Message);
                Reset();
                
            }
        }

        public void OpenRenew(string RenId)
        {
            string ReqId = RenId;
            string cert = "";
            try
            {
                cert = RenewManager.Check(ReqId);
            }
            catch (ManagerException ex)
            {
                MsgBox.Rejected(ex.Message);
                Reset();
                return;
            }
            if (string.IsNullOrEmpty(cert))
            {
                CurrentReqId = ReqId;


                X509Certificate r = RenewManager.Get(ReqId);
                ShowCertificate(r);
            }
            else
            {
                MsgBox.VerifyOk();
                RenewAccepted(cert, null);
            }
        }

        private void ShowCertificate(X509Certificate x509Certificate)
        {
            Certificato = x509Certificate;
            certificateViewControl.EditMode = false;

            certificateViewControl.PublicKeyAlgorithm = "rsaEncryption";
            certificateViewControl.PublicKey = Certificato.PublicKey.GetRSA().PublicModulus.ToHexString();
            certificateViewControl.SubjectC = Certificato.Subject.Country;
            certificateViewControl.SubjectO = Certificato.Subject.Organization;
            certificateViewControl.SubjectOU = Certificato.Subject.OrganizationUnit;
            certificateViewControl.SubjectCN = Certificato.Subject.Common;

            certificateViewControl.Version = "3";
            certificateViewControl.Serial = Certificato.SerialNumber.ToString();
            certificateViewControl.NotBefore = Certificato.NotBefore.ToString();
            certificateViewControl.NotAfter = Certificato.NotAfter.ToString();
            certificateViewControl.AlgorithmID = "rsaEncryption";
            certificateViewControl.IssuerC = Certificato.Issuer.Country;
            certificateViewControl.IssuerO = Certificato.Issuer.Organization;
            certificateViewControl.IssuerOU = Certificato.Issuer.OrganizationUnit;
            certificateViewControl.IssuerCN = Certificato.Issuer.Common;

            certificateViewControl.DigitalSignature = X509Manager.IsSignAllowed(Certificato);
            certificateViewControl.KeyEncipherment = X509Manager.IsEncipherAllowed(Certificato);

            certificateViewControl.SubjectEmail = X509Manager.GetEmail(Certificato);

            RequestButton.Enabled = false;
            VerifyButton.Enabled = true;
        }
    }
}
